namespace YXShop.ExcelLite
{
    using System;
    using System.Text.RegularExpressions;

    internal class Ref3dFormulaToken : RefFormulaToken
    {
        public static readonly Regex IsCell3DRegex = new Regex(@"(?<Sheet>[\S ]+)[\!](?<Column>[\$]?[A-Z]+)(?<Row>[\$]?\d+)", regexOptions);
        private ushort refIndex;
        private static RegexOptions regexOptions = RegexOptions.Compiled;
        private string sheet;
        private ExcelWorksheetCollection workbook;

        public Ref3dFormulaToken(FormulaTokenCode code) : base(code, 7)
        {
            this.refIndex = 0;
        }

        public override byte[] ConvertToBytes()
        {
            byte[] array = new byte[this.Size];
            array[0] = base.Code;
            if (this.sheet != null)
            {
                this.SetSheet(this.sheet);
            }
            BitConverter.GetBytes(this.refIndex).CopyTo(array, 1);
            BitConverter.GetBytes(base.row).CopyTo(array, 3);
            array[5] = base.Column;
            array[6] = base.options;
            return array;
        }

        public override void DelayInitialize(object[] data)
        {
            this.workbook = data[1] as ExcelWorksheetCollection;
            this.Set3dCell(data[0] as string);
        }

        public override void Read(byte[] rpnBytes, int startIndex)
        {
            this.refIndex = BitConverter.ToUInt16(rpnBytes, startIndex + 1);
            base.row = BitConverter.ToUInt16(rpnBytes, startIndex + 3);
            base.column = rpnBytes[startIndex++];
            base.options = rpnBytes[startIndex];
        }

        private void Set3dCell(string cell)
        {
            Match match = IsCell3DRegex.Match(cell);
            this.sheet = match.Groups["Sheet"].Value;
            string row = match.Groups["Row"].Value;
            string column = match.Groups["Column"].Value;
            base.SetCell(row, column);
            this.SetSheet(this.sheet);
        }

        private void SetSheet(string sheet)
        {
            this.refIndex = this.workbook.AddSheetReference(sheet);
        }

        public override string ToString()
        {
            return (this.sheet + "!" + base.ToString());
        }
    }
}

